﻿
/**
//  frmScheduleScreen.cs
//  Marquee Moment
//  Copyright 2011 Systematix Technocrates. All rights reserved.
**/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Data.SqlClient;
using MarqueeMoment.Entities;
using NLog;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace MarqueeMoment.Forms
{
    public partial class frmScheduleScreen : Form
    {
        #region User defined variables
        private bool _imageFromArchive = false;
        private ArchiveEntity _archive = null;

        private bool _imageFromSchedule = false;
        private ScheduleEntity _schedule = null;
        
        private DateTime _varTime = DateTime.Now.AddMinutes(-1);
        private Int32 _scheduleId = 0;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        #endregion User defined variables

        #region Constructor
        public frmScheduleScreen()
        {
            logger.Info("On frmScheduleScreen()");
            InitializeComponent();

            _imageFromArchive = false;
            _archive = null;
            _imageFromSchedule = false;
            _schedule = null;
            lbBack.Text = "Back to Composition Review";
            InitializeValues();
        }

        public frmScheduleScreen(ArchiveEntity archive)
        {
            logger.Info("On frmScheduleScreen(ArchiveEntity archive)");
            InitializeComponent();
            _imageFromArchive = true;
            _archive = archive;
            _imageFromSchedule = false;
            _schedule = null;
            lbBack.Text = "Back to Archive";
            InitializeValues();
        }

        public frmScheduleScreen(ScheduleEntity schedule)
        {
            logger.Info("On frmScheduleScreen(ScheduleEntity schedule)");
            InitializeComponent();
            _imageFromSchedule = true;
            _schedule = schedule;
            _imageFromArchive = false;
            _archive = null;
            lbBack.Text = "Back to Main Menu";
            InitializeValues();
        }
        #endregion Constructor
                
        #region For User Defined Methods
        /// <summary>
        /// To Show Time on Time Box
        /// </summary>
        private void ShowTime()
        {
            String currentTime = String.Empty;
            var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            currentTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZone).ToLongTimeString();
            lblPM.Text = currentTime.Substring(currentTime.Length - 2);
            currentTime = currentTime.Substring(0, currentTime.Length - 3);

            lblT8.Text = currentTime.Substring(currentTime.Length - 1);
            lblT7.Text = currentTime.Substring(currentTime.Length - 2, 1);
            lblT6.Text = currentTime.Substring(currentTime.Length - 3, 1);
            lblT5.Text = currentTime.Substring(currentTime.Length - 4, 1);
            lblT4.Text = currentTime.Substring(currentTime.Length - 5, 1);
            lblT3.Text = currentTime.Substring(currentTime.Length - 6, 1);
            lblT2.Text = currentTime.Substring(currentTime.Length - 7, 1);

            if (currentTime.Length == 7)
                lblT1.Text = String.Empty;
            else
                lblT1.Text = currentTime.Substring(currentTime.Length - 8, 1);
        }

        private void updateTime()
        {
            ShowTime();

            var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            DateTime validateTime = TimeZoneInfo.ConvertTime(DateTime.Now.AddMinutes(6), timeZone);
                
            
            validateTime = validateTime.AddSeconds(-validateTime.Second);
            validateTime = validateTime.AddMilliseconds(-validateTime.Millisecond);

            TimeSpan dateDiff = validateTime.Subtract(_varTime);
            if (dateDiff.Minutes == 0)
                return;
            
            _varTime = validateTime;

            List<DateTime> dateList = GetValidTimeList(validateTime);
            
            if (dateList.Count == 6)
            {
                lblAirTime1.Text = dateList[0].ToLongTimeString();
                lblAirTime2.Text = dateList[1].ToLongTimeString();
                lblAirTime3.Text = dateList[2].ToLongTimeString();
                lblAirTime4.Text = dateList[3].ToLongTimeString();
                lblAirTime5.Text = dateList[4].ToLongTimeString();
                lblAirTime6.Text = dateList[5].ToLongTimeString();

            }
        }

        private List<DateTime> GetValidTimeList(DateTime validateTime)
        {
            List<DateTime> dateList = new List<DateTime>();   

            for (Int32 count = 0; count < 6; count++)
            {
                while (!CheckValidTime(validateTime))
                {
                    validateTime = validateTime.AddMinutes(2);
                }
                dateList.Add(validateTime);
                validateTime = validateTime.AddMinutes(2);

            }
            
            return dateList;
        
        }

        private bool CheckValidTime(DateTime validateTime)
        {
            bool isValidTime = true;
            ScheduleEntity schedule = ScheduleEntity.Select(validateTime, _scheduleId);       //_scheduleId = 0
            if (schedule != null)
            {
                isValidTime = false;
            }


            return isValidTime;
        }


        private void uploadComposedPhoto()
        {
            logger.Info("On uploadComposedPhoto()");
            try
            {
                Bitmap newimg = new Bitmap(MarqueeMoment.Entities.Common.composedPhotoPath());
                picboxPhoto.SizeMode = PictureBoxSizeMode.StretchImage;
                picboxPhoto.Image = (Image)newimg;
                picboxPhoto.Refresh();
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error upload composed photo");
            }
        }

        /// <summary>
        /// release picture box
        /// </summary>
        private void releasePicBox()
        {
            logger.Info("On releasePicBox()");
            if (picboxPhoto.Image != null)
                picboxPhoto.Image.Dispose();

        }

        /// <summary>
        /// To save the image in the DB
        /// </summary>
        /// <param name="imagename">ImageName is the Path of the Image</param>
        private SqlParameter getImageSqlParameter(string imagePath)
        {
            logger.Info("On getImageSqlParameter(string imagePath) with imagePath:" + imagePath);
            try
            {
                if ((!String.IsNullOrEmpty(imagePath)) && (File.Exists(imagePath)))
                {
                    FileStream fs;
                    fs = new FileStream(@imagePath, FileMode.Open, FileAccess.Read);
                    byte[] picbyte = new byte[fs.Length];
                    fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length));
                    fs.Close();

                    SqlParameter picparameter = new SqlParameter();
                    picparameter.SqlDbType = SqlDbType.Image;
                    picparameter.ParameterName = "ImageData";
                    picparameter.Value = picbyte;
                    
                    return picparameter;
                }

            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error on saving imageo");

            }
            return null;

        }

        /// <summary>
        /// To save image at user directory
        /// </summary>
        private void saveImageToUserDir(String imagePath, String imageName)
        {
            logger.Info("On saveImageToUserDir(String imagePath, String imageName) with imagePath:" + imagePath + " imageName:" + imageName);
            try
            {
                if (!Directory.Exists(Common.uploadPhotoDirectoryPath))
                {
                    Dialogs.Exclamation("Invalid Upload Directory Path, add proper path in XML Configuration File for key: UploadPhotoDirectoryPath.");
                    return;
                }
                if (File.Exists(imagePath))
                {
                    File.Copy(imagePath, Common.uploadPhotoDirectoryPath + @"\" + imageName, true);
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error on saving photo on Network Directory");

            }
        }
        
        
        /// <summary>
        /// To add schedule in DB
        /// </summary>
        /// <param name="sender"> Sender is a button object, use to get selected time </param>
        private void AddSchedule(object sender)
        {
            Label lblAirTime = sender as Label;
            if (lblAirTime != null)
            {
                logger.Info("On AddSchedule(object sender) with Air Time:" + lblAirTime.Text);
                DateTime currentTime = Convert.ToDateTime(lblAirTime.Text);

                if (picboxPhoto.Image != null)
                {
                    try
                    {
                    //    if (!Directory.Exists(Common.uploadPhotoDirectoryPath))
                     //   {
                            logger.Info("On AddSchedule(object sender) , Check state bgWorker.IsBusy:" + bgWorker.IsBusy.ToString());
                            if (bgWorker.IsBusy != true)
                            {
                                bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_addToSchedule);
                                bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_addToSchedule);
                                bgWorker.RunWorkerAsync(currentTime);
                            }
                     //   }
                    }
                    catch (Exception exc)
                    {
                        logger.Error(exc.StackTrace);
                        Dialogs.Error("Error on Schedule photo");

                    }
                }
            }
        }

        /// <summary>
        /// To Initialize Values
        /// </summary>
        private void InitializeValues()
        {
            logger.Info("On InitializeValues()");
            try
            {
                var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
                _varTime = TimeZoneInfo.ConvertTime(DateTime.Now.AddMinutes(-1), timeZone);


                updateTime();
                uploadComposedPhoto();
                RefreshGTList();
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error in showing Schedule Screen");
            }
        }
        #endregion For User Defined Methods

        #region For System Events

        private void btnMenu_Click(object sender, EventArgs e)
        {
            logger.Info("On btnMenu_Click(object sender, EventArgs e)");
            frmDialog customBox = new frmDialog("Warning", "All of your changes will be lost, do you wish to continue?");
            if (customBox.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
            {
                this.Close();
            }       

        }

        private void btnBackToComposition_Click(object sender, EventArgs e)
        {
            logger.Info("On btnBackToComposition_Click(object sender, EventArgs e)");
            picboxPhoto.Focus();
            frmDialog customBox = new frmDialog("Warning", "All of your changes will be lost, do you wish to continue?");
            if (customBox.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
            {
                if (_imageFromArchive)
                {
                    logger.Info("On btnBackToComposition_Click(), _imageFromArchive:True");
                    frmArchive.formClose = false;
                }
                else if (_imageFromSchedule)
                {
                    logger.Info("On btnBackToComposition_Click(), _imageFromSchedule:True");                    
                }
                else
                {
                    logger.Info("On btnBackToComposition_Click(), image from compose screen:True");
                    frmComposeMessage.formClose = false;
                }
                this.Close();
            } 
        }

        private void timerSchedule_Tick(object sender, EventArgs e)
        {
            updateTime();
        }

        private void frmScheduleScreen_FormClosing(object sender, FormClosingEventArgs e)
        {
            logger.Info("On frmScheduleScreen_FormClosing(object sender, FormClosingEventArgs e)");
            releasePicBox();
        }

        public void btnArchive_Click(object sender, EventArgs e)
        {
            logger.Info("On btnArchive_Click(object sender, EventArgs e)");
            if (_imageFromArchive)
            {
                Dialogs.Exclamation("Can't save into Archive because image is come from Archive");
                frmArchive.formClose = false;
                this.Close();
            }
            else if (picboxPhoto.Image != null)
            {
                try
                {
                    logger.Info("On btnArchive_Click(), check for background worker state bgWorker.IsBusy:" + bgWorker.IsBusy.ToString());
                    if (bgWorker.IsBusy != true)
                    {
                        bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_addToArchive);
                        bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_addToArchive);
                        bgWorker.RunWorkerAsync();
                    }
                }
                catch (Exception exc)
                {
                    logger.Error(exc.StackTrace);
                    Dialogs.Error("Error on Archive photo");

                }
            }
        }

        private void btnAirTime_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime1);
        }

        private void btnAirTime2_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime2);
        }

        private void btnAirTime3_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime3);
        }

        private void btnAirTime4_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime4);
        }

        private void btnAirTime5_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime5);
        }

        private void btnAirTime6_Click(object sender, EventArgs e)
        {
            AddSchedule(lblAirTime6);
        }

        private void timerMinute_Tick(object sender, EventArgs e)
        {
            RefreshGTList();
        }

        #endregion For System Events

        #region BackgroundWorker

        private void bgWorker_DoWork_addToSchedule(object sender, DoWorkEventArgs e)
        { 
                logger.Info("On bgWorker_DoWork_addToSchedule(object sender, DoWorkEventArgs e)");
                String imagePath = MarqueeMoment.Entities.Common.composedPhotoPath();

                Object objDateTime = e.Argument as Object;
                if (objDateTime != null)
                {
                    DateTime currentTime = (DateTime)objDateTime;
                    SqlParameter picparameter = getImageSqlParameter(imagePath);
                    if (picparameter != null)
                    {
                        Int32 imageID = ImageEntity.Insert(picparameter);
                        ImageEntity image = ImageEntity.Select(imageID);
                        if (image != null)
                        {
                            ScheduleEntity schedule = new ScheduleEntity();
                            schedule.ImageId = image.ImageId;
                            schedule.ScheduleTime = currentTime;
                            if (Directory.Exists(Common.uploadPhotoDirectoryPath))
                            {
                                ScheduleEntity.Insert(schedule);
                            }

                            String ImageName = "MM_" + currentTime.ToString("MM-dd-yyyy_HH_mm_ss") + ".jpg";

                            if (_imageFromArchive && _archive != null)
                            {
                                ImageEntity.Delete(_archive.ImageId);
                                logger.Info("On bgWorker_DoWork_addToSchedule() , image deleted with _archive.ImageId:" + _archive.ImageId.ToString());
                            }
                            else if (_imageFromSchedule && _schedule != null)
                            {
                                ImageEntity.Delete(_schedule.ImageId);
                                logger.Info("On bgWorker_DoWork_addToSchedule() , image deleted with _schedule.ImageId:" + _schedule.ImageId.ToString());
                                Common.DeleteFromNetworkResource(_schedule);
                                logger.Info("On bgWorker_DoWork_addToSchedule() , image deleted from Network path");
                            }

                            e.Result = ImageName;
                        }
                    }
                }  
        }

        private void bgWorker_Completed_addToSchedule(object sender, RunWorkerCompletedEventArgs e)
        {
                logger.Info("On bgWorker_Completed_addToSchedule(object sender, RunWorkerCompletedEventArgs e)");
                String ImageName = e.Result as String;
                if (ImageName != null)
                {
                    String networkImagePath = Common.GetUserDirLOC(ImageName);
                    if (networkImagePath == null)
                    {
                        logger.Error("Error in bgWorker_Completed_addToSchedule(object sender, RunWorkerCompletedEventArgs e)");
                        Dialogs.Error("Network path not found, image not saved in network drive");
                        bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_addToArchive);
                        bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_addToArchive);
                        bgWorker.RunWorkerAsync();
                        return;
                    }
                    String imagePath = MarqueeMoment.Entities.Common.composedPhotoPath();
                    if (File.Exists(imagePath))
                    {
                        Bitmap tempImage = new Bitmap(Common.composedPhotoPath());
                        Bitmap img = new Bitmap(tempImage);
                        tempImage.Dispose();
                        Image topImage = (Image)img;

                        Bitmap tempImage2 = new Bitmap(Common.bottomImagePath);
                        Bitmap img2 = new Bitmap(tempImage2);
                        tempImage2.Dispose();
                        Image bottomImage = (Image)img2;

                        logger.Info("On bgWorker_Completed_addToSchedule(), creating image to save in network path");
                        using (topImage)
                        {
                            using (var bitmap = new Bitmap(753, 352))
                            {
                                using (var canvas = Graphics.FromImage(bitmap))
                                {
                                    canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                    canvas.DrawImage(topImage, 0, 0, 753, 176);
                                    canvas.DrawImage(bottomImage, 0, 176, 753, 176);
                                    canvas.Save();
                                }
                                try
                                {
                                    bitmap.Save(networkImagePath, ImageFormat.Png);
                                    logger.Info("On bgWorker_Completed_addToSchedule(), image saved in network path");
                                    this.Close();
                                }
                                catch (Exception exc)
                                {
                                    logger.Error(exc.StackTrace);
                                    Dialogs.Error("Error at saving image to network drive");
                                }
                            }
                        }

                    }
                }
                    bgWorker.DoWork -= bgWorker_DoWork_addToSchedule;
                    bgWorker.RunWorkerCompleted -= bgWorker_Completed_addToSchedule;       
        }

        public void bgWorker_DoWork_addToArchive(object sender, DoWorkEventArgs e)
        {
            logger.Info("On bgWorker_DoWork_addToArchive(object sender, DoWorkEventArgs e)");
            Boolean status = false;
            String imagePath = MarqueeMoment.Entities.Common.composedPhotoPath();
            SqlParameter picparameter = getImageSqlParameter(imagePath);
            if (picparameter != null)
            {
                Int32 imageID = ImageEntity.Insert(picparameter);
                ImageEntity image = ImageEntity.Select(imageID);
                if (image != null)
                {
                    ArchiveEntity archive = new ArchiveEntity();
                    archive.ImageId = image.ImageId;
                    var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
                    archive.ArchiveTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZone);
                    ArchiveEntity.Insert(archive);
                    logger.Info("On bgWorker_DoWork_addToArchive(), Record inserted into achive table");
                    
                    if (_imageFromSchedule && _schedule != null)
                    {
                        logger.Info("On bgWorker_DoWork_addToArchive(), deleting old record from schedule table");
                        ImageEntity.Delete(_schedule.ImageId);

                        logger.Info("On bgWorker_DoWork_addToArchive(), deleting image from network location");
                        Common.DeleteFromNetworkResource(_schedule);
                        logger.Info("On bgWorker_DoWork_addToArchive(), image deleted from network location");
                    }
                    status = true;
                }
            }


            e.Result = status;
        }

        private void bgWorker_Completed_addToArchive(object sender, RunWorkerCompletedEventArgs e)
        {
            logger.Info("On bgWorker_Completed_addToArchive(object sender, RunWorkerCompletedEventArgs e)");
            Object objStatus = e.Result as Object;
            if (objStatus != null)
            {
                if ((Boolean)objStatus)
                {
                    timerMinute.Enabled = false;
                    this.Visible = false;
                    frmArchive formArchive = new frmArchive();
                    formArchive.ShowDialog();
                    this.Close();
                }
            }


            bgWorker.DoWork -= bgWorker_DoWork_addToArchive;
            bgWorker.RunWorkerCompleted -= bgWorker_Completed_addToArchive;
        }


        #endregion BackgroundWorker

        #region Grid Schedule
       
        /// <summary>
        /// Refresh data of list
        /// </summary>
        private void RefreshGTList()
        {
            logger.Info("On RefreshGTList()");
            DataTable dtGTSchedule = null; 
            DataSet dataset = ScheduleEntity.SelectAllScheduleWithImage();
            if (dataset != null && dataset.Tables.Count > 0)
            {
                if (pnlList.Controls.Count > 0)
                    pnlList.Controls.Clear();

                //for (int count = 0; count < pnlList.Controls.Count; count++)
                //{
                //    ScheduleControl listUserControl = pnlList.Controls[count] as ScheduleControl;
                //    if (listUserControl != null)
                //        if (listUserControl.picBox.Image != null)
                //            listUserControl.picBox.Image.Dispose();

                //}
                dtGTSchedule = dataset.Tables[0];
                ScheduleControl userControl;
                Int32 yPOS = 20;
               
                for (int count = 0; count < dtGTSchedule.Rows.Count; count++)
                {
                    userControl = new ScheduleControl((Int32)dtGTSchedule.Rows[count]["ScheduleId"]);

                    DateTime dtScheduletime = (DateTime)dtGTSchedule.Rows[count]["ScheduleTime"];
                    
                    userControl.lblTime.Text = dtScheduletime.ToLongTimeString();
                    if (dtGTSchedule.Rows.Count > 3)
                        userControl.Width = pnlList.Width - 22;
                    else
                        userControl.Width = pnlList.Width - 2;

                    if (userControl.picBox.Image != null)
                        userControl.picBox.Image.Dispose();
                    
                    byte[] blob = (byte[])dtGTSchedule.Rows[count]["ImageData"];
                    MemoryStream ms = new MemoryStream(blob);
                    Image returnImage = Image.FromStream(ms);

                    userControl.picBox.Image = returnImage;
                    userControl.picBox.SizeMode = PictureBoxSizeMode.StretchImage;
                    userControl.picBox.Refresh();

                    userControl.Location = new System.Drawing.Point(2, yPOS);
                    pnlList.Controls.Add(userControl);

                    yPOS = yPOS + userControl.Height + 10;
                }
            }

        }

        
        
        #endregion Grid Schedule

    }
}
